home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MOR55SRC.ZIP / MORIA / SOURCE / MISC1.C < prev    next >
C/C++ Source or Header  |  1992-12-07  |  24KB  |  1,105 lines

  1. /* source/misc1.c: misc utility and initialization code, magic objects code
  2.  
  3.    Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  4.  
  5.    This software may be copied and distributed for educational, research, and
  6.    not for profit purposes provided that this copyright and statement are
  7.    included in all such copies. */
  8.  
  9. #include "config.h"
  10. #include "constant.h"
  11. #include "types.h"
  12. #include "externs.h"
  13.  
  14. #ifdef __TURBOC__
  15. #include    <stdlib.h>
  16. #endif
  17.  
  18. #ifdef Pyramid
  19. #include <sys/time.h>
  20. #else
  21. #include <time.h>
  22. #endif
  23. #if !defined(GEMDOS) && !defined(MAC) && !defined(AMIGA)
  24. #ifndef VMS
  25. #include <sys/types.h>
  26. #else
  27. #include <types.h>
  28. #endif
  29. #endif
  30.  
  31. #if !defined(ATARIST_MWC) && !defined(MAC) && !defined(VMS) && !defined(AMIGA)
  32. long time();
  33. #endif
  34. struct tm *localtime();
  35.  
  36. #if defined(LINT_ARGS)
  37. static void compact_objects(void);
  38. #endif
  39.  
  40.  
  41. /* gets a new random seed for the random number generator */
  42. void init_seeds(seed)
  43. int32u seed;
  44. {
  45.   register int32u clock_var;
  46.  
  47.   if (seed == 0)
  48. #ifdef MAC
  49.     clock_var = time((time_t *)0);
  50. #else
  51.     clock_var = time((long *)0);
  52. #endif
  53.   else
  54.     clock_var = seed;
  55.   randes_seed = (int32) clock_var;
  56.  
  57.   clock_var += 8762;
  58.   town_seed = (int32) clock_var;
  59.  
  60.   clock_var += 113452L;
  61.   set_rnd_seed(clock_var);
  62.   /* make it a little more random */
  63.   for (clock_var = randint(100); clock_var != 0; clock_var--)
  64.     (void) rnd();
  65. }
  66.  
  67. /* holds the previous rnd state */
  68. static int32u old_seed;
  69.  
  70. /* change to different random number generator state */
  71. void set_seed(seed)
  72. int32u seed;
  73. {
  74.   old_seed = get_rnd_seed ();
  75.  
  76.   /* want reproducible state here */
  77.   set_rnd_seed (seed);
  78. }
  79.  
  80.  
  81. /* restore the normal random generator state */
  82. void reset_seed()
  83. {
  84.   set_rnd_seed (old_seed);
  85. }
  86.  
  87.  
  88. /* Check the day-time strings to see if open        -RAK-    */
  89. int check_time()
  90. {
  91. #ifdef MORIA_HOU
  92.   long clock_var;
  93.   register struct tm *tp;
  94.  
  95. #ifdef MAC
  96.   clock_var = time((time_t *)0);
  97. #else
  98.   clock_var = time((long *)0);
  99. #endif
  100.   tp = localtime(&clock_var);
  101.   if (days[tp->tm_wday][tp->tm_hour+4] == 'X')
  102.     return TRUE;
  103.   else
  104.     return FALSE;
  105. #else
  106.   return TRUE;
  107. #endif
  108. }
  109.  
  110.  
  111. /* Generates a random integer x where 1<=X<=MAXVAL    -RAK-    */
  112. int randint(maxval)
  113. int maxval;
  114. {
  115.   register long randval;
  116.  
  117.   randval = rnd ();
  118.   return ((int)(randval % maxval) + 1);
  119. }
  120.  
  121. /* Generates a random integer number of NORMAL distribution -RAK-*/
  122. int randnor(mean, stand)
  123. int mean, stand;
  124. {
  125.   register int tmp, offset, low, iindex, high;
  126.  
  127. #if 0
  128.   /* alternate randnor code, slower but much smaller since no table */
  129.   /* 2 per 1,000,000 will be > 4*SD, max is 5*SD */
  130.   tmp = damroll(8, 99);     /* mean 400, SD 81 */
  131.   tmp = (tmp - 400) * stand / 81;
  132.   return tmp + mean;
  133. #endif
  134.  
  135.   tmp = randint(MAX_SHORT);
  136.  
  137.   /* off scale, assign random value between 4 and 5 times SD */
  138.   if (tmp == MAX_SHORT)
  139.     {
  140.       offset = 4 * stand + randint(stand);
  141.  
  142.       /* one half are negative */
  143.       if (randint(2) == 1)
  144.     offset = -offset;
  145.  
  146.       return mean + offset;
  147.     }
  148.  
  149.   /* binary search normal normal_table to get index that matches tmp */
  150.   /* this takes up to 8 iterations */
  151.   low = 0;
  152.   iindex = NORMAL_TABLE_SIZE >> 1;
  153.   high = NORMAL_TABLE_SIZE;
  154.   while (TRUE)
  155.     {
  156.       if ((normal_table[iindex] == tmp) || (high == (low+1)))
  157.     break;
  158.       if (normal_table[iindex] > tmp)
  159.     {
  160.       high = iindex;
  161.       iindex = low + ((iindex - low) >> 1);
  162.     }
  163.       else
  164.     {
  165.       low = iindex;
  166.       iindex = iindex + ((high - iindex) >> 1);
  167.     }
  168.     }
  169.  
  170.   /* might end up one below target, check that here */
  171.   if (normal_table[iindex] < tmp)
  172.     iindex = iindex + 1;
  173.  
  174.   /* normal_table is based on SD of 64, so adjust the index value here,
  175.      round the half way case up */
  176.   offset = ((stand * iindex) + (NORMAL_TABLE_SD >> 1)) / NORMAL_TABLE_SD;
  177.  
  178.   /* one half should be negative */
  179.   if (randint(2) == 1)
  180.     offset = -offset;
  181.  
  182.   return mean + offset;
  183. }
  184.  
  185.  
  186. /* Returns position of first set bit            -RAK-    */
  187. /*     and clears that bit */
  188. int bit_pos(test)
  189. int32u *test;
  190. {
  191.   register int i;
  192.   register int32u mask = 0x1;
  193.  
  194.   for (i = 0; i < sizeof(*test)*8; i++) {
  195.     if (*test & mask) {
  196.       *test &= ~mask;
  197.       return(i);
  198.     }
  199.     mask <<= 1;
  200.   }
  201.  
  202.   /* no one bits found */
  203.   return(-1);
  204. }
  205.  
  206. /* Checks a co-ordinate for in bounds status        -RAK-    */
  207. int in_bounds(y, x)
  208. int y, x;
  209. {
  210.   if ((y > 0) && (y < cur_height-1) && (x > 0) && (x < cur_width-1))
  211.     return(TRUE);
  212.   else
  213.     return(FALSE);
  214. }
  215.  
  216.  
  217. /* Calculates current boundaries                -RAK-    */
  218. void panel_bounds()
  219. {
  220.   panel_row_min = panel_row*(SCREEN_HEIGHT/2);
  221.   panel_row_max = panel_row_min + SCREEN_HEIGHT - 1;
  222.   panel_row_prt = panel_row_min - 1;
  223.   panel_col_min = panel_col*(SCREEN_WIDTH/2);
  224.   panel_col_max = panel_col_min + SCREEN_WIDTH - 1;
  225.   panel_col_prt = panel_col_min - 13;
  226. }
  227.  
  228.  
  229. /* Given an row (y) and col (x), this routine detects  -RAK-    */
  230. /* when a move off the screen has occurred and figures new borders.
  231.    Force forcses the panel bounds to be recalculated, useful for 'W'here. */
  232. int get_panel(y, x, force)
  233. int y, x, force;
  234. {
  235.   register int prow, pcol;
  236.   register int panel;
  237.  
  238.   prow = panel_row;
  239.   pcol = panel_col;
  240.   if (force || (y < panel_row_min + 2) || (y > panel_row_max - 2))
  241.     {
  242.       prow = ((y - SCREEN_HEIGHT/4)/(SCREEN_HEIGHT/2));
  243.       if (prow > max_panel_rows)
  244.     prow = max_panel_rows;
  245.       else if (prow < 0)
  246.     prow = 0;
  247.     }
  248.   if (force || (x < panel_col_min + 3) || (x > panel_col_max - 3))
  249.     {
  250.       pcol = ((x - SCREEN_WIDTH/4)/(SCREEN_WIDTH/2));
  251.       if (pcol > max_panel_cols)
  252.     pcol = max_panel_cols;
  253.       else if (pcol < 0)
  254.     pcol = 0;
  255.     }
  256.   if ((prow != panel_row) || (pcol != panel_col))
  257.     {
  258.       panel_row = prow;
  259.       panel_col = pcol;
  260.       panel_bounds();
  261.       panel = TRUE;
  262.       /* stop movement if any */
  263.       if (find_bound)
  264.     end_find();
  265.     }
  266.   else
  267.     panel = FALSE;
  268.   return(panel);
  269. }
  270.  
  271.  
  272. /* Tests a given point to see if it is within the screen -RAK-    */
  273. /* boundaries.                              */
  274. int panel_contains(y, x)
  275. register int y, x;
  276. {
  277.   if ((y >= panel_row_min) && (y <= panel_row_max) &&
  278.       (x >= panel_col_min) && (x <= panel_col_max))
  279.     return (TRUE);
  280.   else
  281.     return (FALSE);
  282. }
  283.  
  284.  
  285. /* Distance between two points                -RAK-    */
  286. int distance(y1, x1, y2, x2)
  287. int y1, x1, y2, x2;
  288. {
  289.   register int dy, dx;
  290.  
  291.   dy = y1 - y2;
  292.   if (dy < 0)
  293.     dy = -dy;
  294.   dx = x1 - x2;
  295.   if (dx < 0)
  296.     dx = -dx;
  297.  
  298.   return ((((dy + dx) << 1) - (dy > dx ? dx : dy)) >> 1);
  299. }
  300.  
  301. /* Checks points north, south, east, and west for a wall -RAK-    */
  302. /* note that y,x is always in_bounds(), i.e. 0 < y < cur_height-1, and
  303.    0 < x < cur_width-1    */
  304. int next_to_walls(y, x)
  305. register int y, x;
  306. {
  307.   register int i;
  308.   register cave_type *c_ptr;
  309.  
  310.   i = 0;
  311.   c_ptr = &cave[y-1][x];
  312.   if (c_ptr->fval >= MIN_CAVE_WALL)
  313.     i++;
  314.   c_ptr = &cave[y+1][x];
  315.   if (c_ptr->fval >= MIN_CAVE_WALL)
  316.     i++;
  317.   c_ptr = &cave[y][x-1];
  318.   if (c_ptr->fval >= MIN_CAVE_WALL)
  319.     i++;
  320.   c_ptr = &cave[y][x+1];
  321.   if (c_ptr->fval >= MIN_CAVE_WALL)
  322.     i++;
  323.  
  324.   return(i);
  325. }
  326.  
  327.  
  328. /* Checks all adjacent spots for corridors        -RAK-    */
  329. /* note that y, x is always in_bounds(), hence no need to check that
  330.    j, k are in_bounds(), even if they are 0 or cur_x-1 is still works */
  331. int next_to_corr(y, x)
  332. register int y, x;
  333. {
  334.   register int k, j, i;
  335.   register cave_type *c_ptr;
  336.  
  337.   i = 0;
  338.   for (j = y - 1; j <= (y + 1); j++)
  339.     for (k = x - 1; k <= (x + 1); k++)
  340.       {
  341.     c_ptr = &cave[j][k];
  342.     /* should fail if there is already a door present */
  343.     if (c_ptr->fval == CORR_FLOOR
  344.         && (c_ptr->tptr == 0 || t_list[c_ptr->tptr].tval < TV_MIN_DOORS))
  345.       i++;
  346.       }
  347.   return(i);
  348. }
  349.  
  350.  
  351. /* generates damage for 2d6 style dice rolls */
  352. int damroll(num, sides)
  353. int num, sides;
  354. {
  355.   register int i, sum = 0;
  356.  
  357.   for (i = 0; i < num; i++)
  358.     sum += randint(sides);
  359.   return(sum);
  360. }
  361.  
  362. int pdamroll(array)
  363. int8u *array;
  364. {
  365.   return damroll((int)array[0], (int)array[1]);
  366. }
  367.  
  368.  
  369. /* A simple, fast, integer-based line-of-sight algorithm.  By Joseph Hall,
  370.    4116 Brewster Drive, Raleigh NC 27606.  Email to jnh@ecemwl.ncsu.edu.
  371.  
  372.    Returns TRUE if a line of sight can be traced from x0, y0 to x1, y1.
  373.  
  374.    The LOS begins at the center of the tile [x0, y0] and ends at
  375.    the center of the tile [x1, y1].  If los() is to return TRUE, all of
  376.    the tiles this line passes through must be transparent, WITH THE
  377.    EXCEPTIONS of the starting and ending tiles.
  378.  
  379.    We don't consider the line to be "passing through" a tile if
  380.    it only passes across one corner of that tile. */
  381.  
  382. /* Because this function uses (short) ints for all calculations, overflow
  383.    may occur if deltaX and deltaY exceed 90. */
  384.  
  385. int los(fromY, fromX, toY, toX)
  386. int fromY, fromX, toY, toX;
  387. {
  388.   register int tmp, deltaX, deltaY;
  389.  
  390.   deltaX = toX - fromX;
  391.   deltaY = toY - fromY;
  392.  
  393.   /* Adjacent? */
  394.   if ((deltaX < 2) && (deltaX > -2) && (deltaY < 2) && (deltaY > -2))
  395.     return TRUE;
  396.  
  397.   /* Handle the cases where deltaX or deltaY == 0. */
  398.   if (deltaX == 0)
  399.     {
  400.       register int p_y;    /* y position -- loop variable    */
  401.  
  402.       if (deltaY < 0)
  403.     {
  404.       tmp = fromY;
  405.       fromY = toY;
  406.       toY = tmp;
  407.     }
  408.       for (p_y = fromY + 1; p_y < toY; p_y++)
  409.     if (cave[p_y][fromX].fval >= MIN_CLOSED_SPACE)
  410.       return FALSE;
  411.       return TRUE;
  412.     }
  413.   else if (deltaY == 0)
  414.     {
  415.       register int px;    /* x position -- loop variable    */
  416.  
  417.       if (deltaX < 0)
  418.     {
  419.       tmp = fromX;
  420.       fromX = toX;
  421.       toX = tmp;
  422.     }
  423.       for (px = fromX + 1; px < toX; px++)
  424.     if (cave[fromY][px].fval >= MIN_CLOSED_SPACE)
  425.       return FALSE;
  426.       return TRUE;
  427.     }
  428.  
  429.   /* Now, we've eliminated all the degenerate cases.
  430.      In the computations below, dy (or dx) and m are multiplied by a
  431.      scale factor, scale = abs(deltaX * deltaY * 2), so that we can use
  432.      integer arithmetic. */
  433.  
  434.   {
  435.     register int px,    /* x position                */
  436.      p_y,        /* y position                */
  437.      scale2;        /* above scale factor / 2        */
  438.     int scale,        /* above scale factor            */
  439.      xSign,        /* sign of deltaX            */
  440.      ySign,        /* sign of deltaY            */
  441.      m;            /* slope or 1/slope of LOS        */
  442.  
  443.     scale2 = abs(deltaX * deltaY);
  444.     scale = scale2 << 1;
  445.     xSign = (deltaX < 0) ? -1 : 1;
  446.     ySign = (deltaY < 0) ? -1 : 1;
  447.  
  448.     /* Travel from one end of the line to the other, oriented along
  449.        the longer axis. */
  450.  
  451.     if (abs(deltaX) >= abs(deltaY))
  452.       {
  453.     register int dy;        /* "fractional" y position    */
  454.     /* We start at the border between the first and second tiles,
  455.        where the y offset = .5 * slope.  Remember the scale
  456.        factor.  We have:
  457.  
  458.        m = deltaY / deltaX * 2 * (deltaY * deltaX)
  459.          = 2 * deltaY * deltaY. */
  460.  
  461.     dy = deltaY * deltaY;
  462.     m = dy << 1;
  463.     px = fromX + xSign;
  464.  
  465.     /* Consider the special case where slope == 1. */
  466.     if (dy == scale2)
  467.       {
  468.         p_y = fromY + ySign;
  469.         dy -= scale;
  470.       }
  471.     else
  472.       p_y = fromY;
  473.  
  474.     while (toX - px)
  475.       {
  476.         if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
  477.           return FALSE;
  478.  
  479.         dy += m;
  480.         if (dy < scale2)
  481.           px += xSign;
  482.         else if (dy > scale2)
  483.           {
  484.         p_y += ySign;
  485.         if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
  486.           return FALSE;
  487.         px += xSign;
  488.         dy -= scale;
  489.           }
  490.         else
  491.           {
  492.         /* This is the case, dy == scale2, where the LOS
  493.            exactly meets the corner of a tile. */
  494.         px += xSign;
  495.         p_y += ySign;
  496.         dy -= scale;
  497.           }
  498.       }
  499.     return TRUE;
  500.       }
  501.     else
  502.       {
  503.     register int dx;        /* "fractional" x position    */
  504.     dx = deltaX * deltaX;
  505.     m = dx << 1;
  506.  
  507.     p_y = fromY + ySign;
  508.     if (dx == scale2)
  509.       {
  510.         px = fromX + xSign;
  511.         dx -= scale;
  512.       }
  513.     else
  514.       px = fromX;
  515.  
  516.     while (toY - p_y)
  517.       {
  518.         if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
  519.           return FALSE;
  520.         dx += m;
  521.         if (dx < scale2)
  522.           p_y += ySign;
  523.         else if (dx > scale2)
  524.           {
  525.         px += xSign;
  526.         if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
  527.           return FALSE;
  528.         p_y += ySign;
  529.         dx -= scale;
  530.           }
  531.         else
  532.           {
  533.         px += xSign;
  534.         p_y += ySign;
  535.         dx -= scale;
  536.           }
  537.       }
  538.     return TRUE;
  539.       }
  540.   }
  541. }
  542.  
  543.  
  544. /* Returns symbol for given row, column            -RAK-    */
  545. unsigned char loc_symbol(y, x)
  546. int y, x;
  547. {
  548.   register cave_type *cave_ptr;
  549.   register struct flags *f_ptr;
  550.  
  551.   cave_ptr = &cave[y][x];
  552.   f_ptr = &py.flags;
  553.  
  554.   if ((cave_ptr->cptr == 1) && (!find_flag || find_prself))
  555.     return '@';
  556.   else if (f_ptr->status & PY_BLIND)
  557.     return ' ';
  558.   else if ((f_ptr->image > 0) && (randint (12) == 1))
  559.     return randint (95) + 31;
  560.   else if ((cave_ptr->cptr > 1) && (m_list[cave_ptr->cptr].ml))
  561.     return c_list[m_list[cave_ptr->cptr].mptr].cchar;
  562.   else if (!cave_ptr->pl && !cave_ptr->tl && !cave_ptr->fm)
  563.     return ' ';
  564.   else if ((cave_ptr->tptr != 0)
  565.        && (t_list[cave_ptr->tptr].tval != TV_INVIS_TRAP))
  566.     return t_list[cave_ptr->tptr].tchar;
  567.   else if (cave_ptr->fval <= MAX_CAVE_FLOOR)
  568.     {
  569. #ifdef MSDOS
  570.       return floorsym;
  571. #else
  572.       return '.';
  573. #endif
  574.     }
  575.   else if (cave_ptr->fval == GRANITE_WALL || cave_ptr->fval == BOUNDARY_WALL
  576.        || highlight_seams == FALSE)
  577.     {
  578. #ifdef MSDOS
  579.       return wallsym;
  580. #else
  581. #ifndef ATARI_ST
  582.       return '#';
  583. #else
  584.       return (unsigned char)240;
  585. #endif
  586. #endif
  587.     }
  588.   else    /* Originally set highlight bit, but that is not portable, now use
  589.        the percent sign instead. */
  590.     {
  591.       return '%';
  592.     }
  593. }
  594.  
  595.  
  596. /* Tests a spot for light or field mark status        -RAK-    */
  597. int test_light(y, x)
  598. int y, x;
  599. {
  600.   register cave_type *cave_ptr;
  601.  
  602.   cave_ptr = &cave[y][x];
  603.   if (cave_ptr->pl || cave_ptr->tl || cave_ptr->fm)
  604.     return(TRUE);
  605.   else
  606.     return(FALSE);
  607. }
  608.  
  609.  
  610. /* Prints the map of the dungeon            -RAK-    */
  611. void prt_map()
  612. {
  613.   register int i, j, k;
  614.   register unsigned char tmp_char;
  615.  
  616.   k = 0;
  617.   for (i = panel_row_min; i <= panel_row_max; i++)  /* Top to bottom */
  618.     {
  619.       k++;
  620.       erase_line (k, 13);
  621.       for (j = panel_col_min; j <= panel_col_max; j++)    /* Left to right */
  622.     {
  623.       tmp_char = loc_symbol(i, j);
  624.       if (tmp_char != ' ')
  625.         print(tmp_char, i, j);
  626.     }
  627.     }
  628. }
  629.  
  630.  
  631. /* Compact monsters                    -RAK-    */
  632. /* Return TRUE if any monsters were deleted, FALSE if could not delete any
  633.    monsters.  */
  634. int compact_monsters()
  635. {
  636.   register int i;
  637.   int cur_dis, delete_any;
  638.   register monster_type *mon_ptr;
  639. #ifdef ATARIST_MWC
  640.   int32 holder;
  641. #endif
  642.  
  643.   msg_print("Compacting monsters...");
  644.  
  645.   cur_dis = 66;
  646.   delete_any = FALSE;
  647.   do
  648.     {
  649.       for (i = mfptr - 1; i >= MIN_MONIX; i--)
  650.     {
  651.       mon_ptr = &m_list[i];
  652.       if ((cur_dis < mon_ptr->cdis) && (randint(3) == 1))
  653.         {
  654.           /* Never compact away the Balrog!! */
  655. #ifdef ATARIST_MWC
  656.           if (c_list[mon_ptr->mptr].cmove & (holder = CM_WIN))
  657. #else
  658.           if (c_list[mon_ptr->mptr].cmove & CM_WIN)
  659. #endif
  660.         /* Do nothing */
  661.         ;
  662.           /* in case this is called from within creatures(), this is a
  663.          horrible hack, the m_list/creatures() code needs to be
  664.          rewritten */
  665.           else if (hack_monptr < i)
  666.         {
  667.           delete_monster(i);
  668.           delete_any = TRUE;
  669.         }
  670.           else
  671.         /* fix1_delete_monster() does not decrement mfptr, so
  672.            don't set delete_any if this was called */
  673.         fix1_delete_monster(i);
  674.         }
  675.     }
  676.       if (!delete_any)
  677.     {
  678.       cur_dis -= 6;
  679.       /* Can't delete any monsters, return failure.  */
  680.       if (cur_dis < 0)
  681.         return FALSE;
  682.     }
  683.     }
  684.   while (!delete_any);
  685.   return TRUE;
  686. }
  687.  
  688.  
  689. /* Add to the players food time                -RAK-    */
  690. void add_food(num)
  691. int num;
  692. {
  693.   register struct flags *p_ptr;
  694.   register int extra, penalty;
  695.  
  696.   p_ptr = &py.flags;
  697.   if (p_ptr->food < 0)    p_ptr->food = 0;
  698.   p_ptr->food += num;
  699.   if (p_ptr->food > PLAYER_FOOD_MAX)
  700.     {
  701.       msg_print("You are bloated from overeating.");
  702.  
  703.       /* Calculate how much of num is responsible for the bloating.
  704.      Give the player food credit for 1/50, and slow him for that many
  705.      turns also.  */
  706.       extra = p_ptr->food - PLAYER_FOOD_MAX;
  707.       if (extra > num)
  708.     extra = num;
  709.       penalty = extra / 50;
  710.  
  711.       p_ptr->slow += penalty;
  712.       if (extra == num)
  713.     p_ptr->food = p_ptr->food - num + penalty;
  714.       else
  715.     p_ptr->food = PLAYER_FOOD_MAX + penalty;
  716.     }
  717.   else if (p_ptr->food > PLAYER_FOOD_FULL)
  718.     msg_print("You are full.");
  719. }
  720.  
  721.  
  722. /* Returns a pointer to next free space            -RAK-    */
  723. /* Returns -1 if could not allocate a monster.  */
  724. int popm()
  725. {
  726.   if (mfptr == MAX_MALLOC)
  727.     {
  728.       if (! compact_monsters())
  729.     return -1;
  730.     }
  731.   return (mfptr++);
  732. }
  733.  
  734.  
  735. /* Gives Max hit points                    -RAK-    */
  736. int max_hp(array)
  737. int8u *array;
  738. {
  739.   return(array[0] * array[1]);
  740. }
  741.  
  742.  
  743. /* Places a monster at given location            -RAK-    */
  744. int place_monster(y, x, z, slp)
  745. register int y, x, z;
  746. int slp;
  747. {
  748.   register int cur_pos;
  749.   register monster_type *mon_ptr;
  750.  
  751.   cur_pos = popm();
  752.   if (cur_pos == -1)
  753.     return FALSE;
  754.   mon_ptr = &m_list[cur_pos];
  755.   mon_ptr->fy = y;
  756.   mon_ptr->fx = x;
  757.   mon_ptr->mptr = z;
  758.   if (c_list[z].cdefense & CD_MAX_HP)
  759.     mon_ptr->hp = max_hp(c_list[z].hd);
  760.   else
  761.     mon_ptr->hp = pdamroll(c_list[z].hd);
  762.   /* the c_list speed value is 10 greater, so that it can be a int8u */
  763.   mon_ptr->cspeed = c_list[z].speed - 10 + py.flags.speed;
  764.   mon_ptr->stunned = 0;
  765.   mon_ptr->cdis = distance(char_row, char_col,y,x);
  766.   mon_ptr->ml = FALSE;
  767.   cave[y][x].cptr = cur_pos;
  768.   if (slp)
  769.     {
  770.       if (c_list[z].sleep == 0)
  771.     mon_ptr->csleep = 0;
  772.       else
  773.     mon_ptr->csleep = (c_list[z].sleep * 2) +
  774.       randint((int)c_list[z].sleep*10);
  775.     }
  776.   else
  777.     mon_ptr->csleep = 0;
  778.   return TRUE;
  779. }
  780.  
  781.  
  782. /* Places a monster at given location            -RAK-    */
  783. void place_win_monster()
  784. {
  785.   register int y, x, cur_pos;
  786.   register monster_type *mon_ptr;
  787.  
  788.   if (!total_winner)
  789.     {
  790.       cur_pos = popm();
  791.       /* Check for case where could not allocate space for the win monster,
  792.      this should never happen.  */
  793.       if (cur_pos == -1)
  794.     abort();
  795.       mon_ptr = &m_list[cur_pos];
  796.       do
  797.     {
  798.       y = randint(cur_height-2);
  799.       x = randint(cur_width-2);
  800.     }
  801.       while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr != 0)
  802.          || (cave[y][x].tptr != 0) ||
  803.           (distance(y,x,char_row, char_col) <= MAX_SIGHT));
  804.       mon_ptr->fy = y;
  805.       mon_ptr->fx = x;
  806.       mon_ptr->mptr = randint(WIN_MON_TOT) - 1 + m_level[MAX_MONS_LEVEL];
  807.       if (c_list[mon_ptr->mptr].cdefense & CD_MAX_HP)
  808.     mon_ptr->hp = max_hp(c_list[mon_ptr->mptr].hd);
  809.       else
  810.     mon_ptr->hp = pdamroll(c_list[mon_ptr->mptr].hd);
  811.       /* the c_list speed value is 10 greater, so that it can be a int8u */
  812.       mon_ptr->cspeed = c_list[mon_ptr->mptr].speed - 10 + py.flags.speed;
  813.       mon_ptr->stunned = 0;
  814.       mon_ptr->cdis = distance(char_row, char_col,y,x);
  815.       cave[y][x].cptr = cur_pos;
  816.       mon_ptr->csleep = 0;
  817.     }
  818. }
  819.  
  820.  
  821. /* Return a monster suitable to be placed at a given level.  This makes
  822.    high level monsters (up to the given level) slightly more common than
  823.    low level monsters at any given level.   -CJS- */
  824. int get_mons_num (level)
  825. int level;
  826. {
  827.   register int i, j, num;
  828.  
  829.   if (level == 0)
  830.     i = randint (m_level[0]) - 1;
  831.   else
  832.     {
  833.       if (level > MAX_MONS_LEVEL)
  834.     level = MAX_MONS_LEVEL;
  835.       if (randint (MON_NASTY) == 1)
  836.     {
  837.       i = randnor (0, 4);
  838.       level = level + abs(i) + 1;
  839.       if (level > MAX_MONS_LEVEL)
  840.         level = MAX_MONS_LEVEL;
  841.     }
  842.       else
  843.     {
  844.       /* This code has been added to make it slightly more likely to
  845.          get the higher level monsters. Originally a uniform
  846.          distribution over all monsters of level less than or equal to the
  847.          dungeon level. This distribution makes a level n monster occur
  848.          approx 2/n% of the time on level n, and 1/n*n% are 1st level. */
  849.  
  850.       num = m_level[level] - m_level[0];
  851.       i = randint (num) - 1;
  852.       j = randint (num) - 1;
  853.       if (j > i)
  854.         i = j;
  855.       level = c_list[i + m_level[0]].level;
  856.     }
  857.       i = randint(m_level[level]-m_level[level-1]) - 1 + m_level[level-1];
  858.     }
  859.   return i;
  860. }
  861.  
  862.  
  863. /* Allocates a random monster                -RAK-    */
  864. void alloc_monster(num, dis, slp)
  865. int num, dis;
  866. int slp;
  867. {
  868.   register int y, x, i;
  869.   int l;
  870.  
  871.   for (i = 0; i < num; i++)
  872.     {
  873.       do
  874.     {
  875.       y = randint(cur_height-2);
  876.       x = randint(cur_width-2);
  877.     }
  878.       while (cave[y][x].fval >= MIN_CLOSED_SPACE || (cave[y][x].cptr != 0) ||
  879.          (distance(y, x, char_row, char_col) <= dis));
  880.  
  881.       l = get_mons_num (dun_level);
  882.       /* Dragons are always created sleeping here, so as to give the player a
  883.      sporting chance.  */
  884.       if (c_list[l].cchar == 'd' || c_list[l].cchar == 'D')
  885.     slp = TRUE;
  886.       /* Place_monster() should always return TRUE here.  It does not
  887.      matter if it fails though.  */
  888.       (void) place_monster(y, x, l, slp);
  889.     }
  890. }
  891.  
  892.  
  893. /* Places creature adjacent to given location        -RAK-    */
  894. int summon_monster(y, x, slp)
  895. int *y, *x;
  896. int slp;
  897. {
  898.   register int i, j, k;
  899.   int l, summon;
  900.   register cave_type *cave_ptr;
  901.  
  902.   i = 0;
  903.   summon = FALSE;
  904.   l = get_mons_num (dun_level + MON_SUMMON_ADJ);
  905.   do
  906.     {
  907.       j = *y - 2 + randint(3);
  908.       k = *x - 2 + randint(3);
  909.       if (in_bounds(j, k))
  910.     {
  911.       cave_ptr = &cave[j][k];
  912.       if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0))
  913.         {
  914.           /* Place_monster() should always return TRUE here.  */
  915.           if (!place_monster(j, k, l, slp))
  916.         return FALSE;
  917.           summon = TRUE;
  918.           i = 9;
  919.           *y = j;
  920.           *x = k;
  921.         }
  922.     }
  923.       i++;
  924.     }
  925.   while (i <= 9);
  926.   return(summon);
  927. }
  928.  
  929.  
  930. /* Places undead adjacent to given location        -RAK-    */
  931. int summon_undead(y, x)
  932. int *y, *x;
  933. {
  934.   register int i, j, k;
  935.   int l, m, ctr, summon;
  936.   register cave_type *cave_ptr;
  937.  
  938.   i = 0;
  939.   summon = FALSE;
  940.   l = m_level[MAX_MONS_LEVEL];
  941.   do
  942.     {
  943.       m = randint(l) - 1;
  944.       ctr = 0;
  945.       do
  946.     {
  947.       if (c_list[m].cdefense & CD_UNDEAD)
  948.         {
  949.           ctr = 20;
  950.           l     = 0;
  951.         }
  952.       else
  953.         {
  954.           m++;
  955.           if (m > l)
  956.         ctr = 20;
  957.           else
  958.         ctr++;
  959.         }
  960.     }
  961.       while (ctr <= 19);
  962.     }
  963.   while(l != 0);
  964.   do
  965.     {
  966.       j = *y - 2 + randint(3);
  967.       k = *x - 2 + randint(3);
  968.       if (in_bounds(j, k))
  969.     {
  970.       cave_ptr = &cave[j][k];
  971.       if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0))
  972.         {
  973.           /* Place_monster() should always return TRUE here.  */
  974.           if (! place_monster(j, k, m, FALSE))
  975.         return FALSE;
  976.           summon = TRUE;
  977.           i = 9;
  978.           *y = j;
  979.           *x = k;
  980.         }
  981.     }
  982.       i++;
  983.     }
  984.   while(i <= 9);
  985.   return(summon);
  986. }
  987.  
  988.  
  989. /* If too many objects on floor level, delete some of them-RAK-    */
  990. static void compact_objects()
  991. {
  992.   register int i, j;
  993.   int ctr, cur_dis, chance;
  994.   register cave_type *cave_ptr;
  995.  
  996.   msg_print("Compacting objects...");
  997.  
  998.   ctr = 0;
  999.   cur_dis = 66;
  1000.   do
  1001.     {
  1002.       for (i = 0; i < cur_height; i++)
  1003.     for (j = 0; j < cur_width; j++)
  1004.       {
  1005.         cave_ptr = &cave[i][j];
  1006.         if ((cave_ptr->tptr != 0)
  1007.         && (distance(i, j, char_row, char_col) > cur_dis))
  1008.           {
  1009.         switch(t_list[cave_ptr->tptr].tval)
  1010.           {
  1011.           case TV_VIS_TRAP:
  1012.             chance = 15;
  1013.             break;
  1014.           case TV_INVIS_TRAP:
  1015.           case TV_RUBBLE:
  1016.           case TV_OPEN_DOOR: case TV_CLOSED_DOOR:
  1017.             chance = 5;
  1018.             break;
  1019.           case TV_UP_STAIR: case TV_DOWN_STAIR:
  1020.           case TV_STORE_DOOR:
  1021.             /* stairs, don't delete them */
  1022.             /* shop doors, don't delete them */
  1023.             chance = 0;
  1024.             break;
  1025.           case TV_SECRET_DOOR: /* secret doors */
  1026.             chance = 3;
  1027.             break;
  1028.           default:
  1029.             chance = 10;
  1030.           }
  1031.         if (randint (100) <= chance)
  1032.           {
  1033.             (void) delete_object(i, j);
  1034.             ctr++;
  1035.           }
  1036.           }
  1037.       }
  1038.       if (ctr == 0)  cur_dis -= 6;
  1039.     }
  1040.   while (ctr <= 0);
  1041.   if (cur_dis < 66)  prt_map();
  1042. }
  1043.  
  1044. /* Gives pointer to next free space            -RAK-    */
  1045. int popt()
  1046. {
  1047.   if (tcptr == MAX_TALLOC)
  1048.     compact_objects();
  1049.   return (tcptr++);
  1050. }
  1051.  
  1052.  
  1053. /* Pushs a record back onto free space list        -RAK-    */
  1054. /* Delete_object() should always be called instead, unless the object in
  1055.    question is not in the dungeon, e.g. in store1.c and files.c */
  1056. void pusht(x)
  1057. register int8u x;
  1058. {
  1059.   register int i, j;
  1060.  
  1061.   if (x != tcptr - 1)
  1062.     {
  1063.       t_list[x] = t_list[tcptr - 1];
  1064.  
  1065.       /* must change the tptr in the cave of the object just moved */
  1066.       for (i = 0; i < cur_height; i++)
  1067.     for (j = 0; j < cur_width; j++)
  1068.       if (cave[i][j].tptr == tcptr - 1)
  1069.         cave[i][j].tptr = x;
  1070.     }
  1071.   tcptr--;
  1072.   invcopy(&t_list[tcptr], OBJ_NOTHING);
  1073. }
  1074.  
  1075.  
  1076. /* Boolean : is object enchanted      -RAK- */
  1077. int magik(chance)
  1078. int chance;
  1079. {
  1080.   if (randint(100) <= chance)
  1081.     return(TRUE);
  1082.   else
  1083.     return(FALSE);
  1084. }
  1085.  
  1086.  
  1087. /* Enchant a bonus based on degree desired -RAK- */
  1088. int m_bonus(base, max_std, level)
  1089. int base, max_std, level;
  1090. {
  1091.   register int x, stand_dev, tmp;
  1092.  
  1093.   stand_dev = (OBJ_STD_ADJ * level / 100) + OBJ_STD_MIN;
  1094.   /* Check for level > max_std since that may have generated an overflow.  */
  1095.   if (stand_dev > max_std || level > max_std)
  1096.     stand_dev = max_std;
  1097.   /* abs may be a macro, don't call it with randnor as a parameter */
  1098.   tmp = randnor(0, stand_dev);
  1099.   x = (abs(tmp) / 10) + base;
  1100.   if (x < base)
  1101.     return(base);
  1102.   else
  1103.     return(x);
  1104. }
  1105.